package com.lnj.exeption.advice;

import com.lnj.exeption.*;
import com.lnj.utils.ResponseResult;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authorization.AuthorizationDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.security.auth.login.AccountExpiredException;
import java.security.SignatureException;

/*
* 全局异常处理器
* -----------------------------------------------
* 请求成功（带数据）			200
* 新增资源成功				201
* 删除资源成功（无数据）		204
* 无需更新					205
* -----------------------------------------------
* 参数错误					400
* 未登录					    401
* 无权限					    403
* 资源不存在				    404
* 日期格式错误				405
* -----------------------------------------------
* 服务器代码异常				500
* 服务暂时不可用				503
* -----------------------------------------------
* */
@Slf4j
@RestControllerAdvice(basePackages = {"com.lnj.controller"})
public class GlobalExceptionHandler {

// ==========================================自定义异常================================================================================================
	/*
	* 处理权限不足异常
	* 403 Forbidden 无权限
	* */
	@ExceptionHandler (InsufficientAuthorException.class)
	public ResponseEntity<ResponseResult<Object>> handleAuthorizationException(InsufficientAuthorException e) {
		
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理参数校验异常
	* 400 Bad Request 参数错误：参数不能为空
	* */
	@ExceptionHandler (ParamIsNullException.class)
	public ResponseEntity<ResponseResult<Object>> handleParamIsNullException(ParamIsNullException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理用户已存在异常
	* 400 Bad Request 参数错误：用户已存在
	* */
	@ExceptionHandler (UserIsExistsException.class)
	public ResponseEntity<ResponseResult<Object>> handleUserIsExistsException(UserIsExistsException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理用户不存在异常
	* 404 Not Found 资源不存在：用户不存在
	* */
	@ExceptionHandler (UserNotFindException.class)
	public ResponseEntity<ResponseResult<Object>> handleUserNotFindException(UserNotFindException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理产品不存在异常
	* 404 Not Found 资源不存在：产品不存在
	* */
	@ExceptionHandler (ProductNotFindException.class)
	public ResponseEntity<ResponseResult<Object>> handleProductNotExistsException(ProductNotFindException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理日期格式异常
	* 405 Method Not Allowed 日期格式错误
	* */
	@ExceptionHandler (DateFormatException.class)
	public ResponseEntity<ResponseResult<Object>> handleDateFormatException(DateFormatException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理分类不存在异常
	* 404 Not Found 资源不存在：分类不存在
	* */
	@ExceptionHandler (CategoryNotExistException.class)
	public ResponseEntity<ResponseResult<Object>> handleCategoryNotExistException(CategoryNotExistException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理订单已评价异常
	* 400 Bad Request 参数错误：订单已评价
	* */
	@ExceptionHandler (OrderIsReviewException.class)
	public ResponseEntity<ResponseResult<Object>> handleOrderIsReviewException(OrderIsReviewException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
	
	/*
	* 处理活动不存在异常
	* 404 Not Found 资源不存在：活动不存在
	* */
	@ExceptionHandler (ActivityNotFindException.class)
	public ResponseEntity<ResponseResult<Object>> handleActivityNotFindException(ActivityNotFindException e) {
		return ResponseEntity.ok(ResponseResult.error(e.getCode(),e.getMessage()));
	}
// ==========================================自定义异常================================================================================================

// =======================================用户登录认证异常================================================================================================

	/**
	 * 处理账户禁用/锁定/过期异常
	 * 403 Forbidden 账户状态异常
	 */
	@ExceptionHandler({DisabledException.class, LockedException.class, AccountExpiredException.class})
	public ResponseEntity<ResponseResult<Object>> handleAccountStatusException(RuntimeException e) {
		return ResponseEntity.status(HttpStatus.FORBIDDEN)
				.body(ResponseResult.error(403,"账户状态异常：" + e.getMessage()));
	}
	
	/**
	 * 处理密码过期异常
	 * 403 Forbidden 密码已过期，请重置密码
	 */
	@ExceptionHandler(CredentialsExpiredException.class)
	public ResponseEntity<ResponseResult<Object>> handleCredentialsExpiredException() {
		return ResponseEntity.status(HttpStatus.FORBIDDEN)
				.body(ResponseResult.error(403,"密码已过期，请重置密码"));
	}
	
	/**
	 * 处理认证服务异常（如数据库连接失败）
	 * 500 Internal Server Error 认证服务暂时不可用，请稍后重试
	 */
	@ExceptionHandler(AuthenticationServiceException.class)
	public ResponseEntity<ResponseResult<Object>> handleAuthenticationServiceException() {
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
				.body(ResponseResult.error(500,"认证服务暂时不可用，请稍后重试"));
	}
	
	/**
	 * 处理JWT相关异常（如签名错误、过期）
	 * 401 Unauthorized 无效的Token
	 */
	@ExceptionHandler({ExpiredJwtException.class, SignatureException.class, MalformedJwtException.class})
	public ResponseEntity<ResponseResult<Object>> handleJwtException(Exception e) {
		return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
				.body(ResponseResult.error(401,"无效的Token：" + e.getMessage()));
	}
	
	/*
	* 授权异常处理
	* 403 Forbidden 权限不足
	* */
	@ExceptionHandler (AuthorizationDeniedException.class)
	public ResponseEntity<ResponseResult<Object>> handleAuthorizationException(AuthorizationDeniedException e) {
		return ResponseEntity.status(HttpStatus.FORBIDDEN)
				.body(ResponseResult.error(403,"权限不足：" + e.getMessage()));
	}
// =======================================用户登录认证异常================================================================================================

// ===========================================其他异常================================================================================================
	
	/*
	* 处理其他异常
	* 500 Internal Server Error 服务器内部错误
	* */
	@ExceptionHandler (Exception.class)
	public ResponseEntity<ResponseResult<Object>> handleGeneralException(Exception e) {
		log.error("系统内部错误", e);
		return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
				.body(ResponseResult.error(500,"服务器内部错误，请稍后重试"));
	}
	
	/*
	* 参数不合理
	* 400 Bad Request 参数错误：参数不合理
	* */
	@ExceptionHandler (IllegalArgumentException.class)
	public ResponseEntity<ResponseResult<Object>> handleIllegalArgumentException(IllegalArgumentException e) {
		return ResponseEntity.status(HttpStatus.BAD_REQUEST)
				.body(ResponseResult.error(400,e.getMessage()));
	}
// ===========================================其他异常================================================================================================

// =========================================框架转换异常================================================================================================
	/*
	* 处理Bean Validation校验失败的异常
	* */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	public ResponseEntity<String> handleValidException(MethodArgumentNotValidException e) {
		// 获取校验失败的错误信息（取第一个错误）
		String errorMsg = e.getBindingResult().getFieldError().getDefaultMessage();
		log.error("产品参数校验失败：{}", errorMsg);
		return ResponseEntity.badRequest().body(errorMsg);
	}
// =========================================框架转换异常================================================================================================
}